package coupon;

import cache.CacheHelper;
import enums.CouponType;
import helper.GlobalConfig;
import models.BaseModel;
import models.constants.DeletedStatus;
import models.merchant.Merchant;
import models.weixin.WebUser;
import order.Order;
import play.Logger;
import play.jobs.Job;
import util.common.ConvertUtil;

import javax.persistence.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * Created by buhaoba on 2016/10/19.
 */
@Entity
@Table(name = "discount_coupons")
public class DiscountCoupon extends BaseModel {


    /**
     * 商户信息
     */
    @JoinColumn(name = "merchant_id")
    @ManyToOne
    public Merchant merchant;


    /**
     * 活动标题
     */
    @Column(name = "title")
    public String title;


    /**
     * 使用的优先级
     */
    @Column(name = "priority")
    public Integer priority;

    /**
     * 开始日期
     */
    @Column(name = "begin_at")
    public Date beginAt;

    /**
     * 开始时间
     */
    @Column(name = "begin_times")
    public String beginTimes;

    /**
     * 结束日期
     */
    @Column(name = "end_at")
    public Date endAt;


    /**
     * 结束时间
     */
    @Column(name = "end_times")
    public String endTimes;

    /**
     * 最小赠送金额
     */
    @Column(name = "min_amount")
    public Double minAmount;

    /**
     * 最大赠送金额
     */
    @Column(name = "max_amount")
    public Double maxAmount;

    /**
     * 平均赠送金额
     */
    @Column(name = "avg_amount")
    public Double avgAmount;

    /**
     * 分多少个跨度
     */
    @Column(name = "grade")
    public Integer grade = 1;

    /**
     * 实际赠送金额
     */
    @Column(name = "amount")
    public Double amount;

    /**
     * 满就送金额
     */
    @Column(name = "full_amount")
    public Double fullAmount;


    /**
     * 可使用最小比例
     */
    @Column(name = "min_proportion")
    public Double minProportion = 0.00D;

    /**
     * 可使用最大比例
     */
    @Column(name = "max_proportion")
    public Double maxProportion = 1.00D;

    /**
     * 平均比例
     */
    @Column(name = "avg_proportion")
    public Double avgProportion = 1.00D;

    /**
     * 类型
     */
    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    public CouponType type;


    /**
     * 是否可累加
     */
    @Column(name = "is_accumulation")
    public Boolean isAccumulation;


    /**
     * 逻辑删除状态
     */
    @Column(name = "deleted")
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted;

    /**
     * 备注
     */
    @Column(name = "remark")
    public String remark;


    /**
     * 根据id查询
     * @param id
     * @return
     */
    public static DiscountCoupon findByDiscountCouponId(long id){
        return DiscountCoupon.find(" id = ? and deleted = ?",id ,DeletedStatus.UN_DELETED).first();
    }

    /**
     * 查询未删除订单
     * @return
     */
    public static List<DiscountCoupon> findByUnDeleted() {
        return DiscountCoupon.find("deleted = ?", DeletedStatus.UN_DELETED).fetch();
    }

    public static List<DiscountCoupon> findByAvailableByMerchant(Merchant merchant) {
        return DiscountCoupon.find("deleted = ? and beginAt < ? and endAt > ? and merchant = ?", DeletedStatus.UN_DELETED, new Date(), new Date(), merchant).fetch();
    }

    public static List<DiscountCoupon> findByAvailableByMerchant(Merchant merchant, CouponType type) {
        return DiscountCoupon.find("deleted = ? and beginAt < ? and endAt > ? and merchant = ? and type = ? ", DeletedStatus.UN_DELETED, new Date(), new Date(), merchant, type).fetch();
    }


    /**
     * 按照商户和活动类型查询结束时间晚于现在时间的抵扣券
     * @param merchant
     * @param type
     * @return
     */
    public static List<DiscountCoupon> findByMerchantAndType(Merchant merchant, CouponType type) {
        return DiscountCoupon.find("deleted = ?  and endAt > ? and merchant = ? and type = ? ", DeletedStatus.UN_DELETED,  new Date(), merchant, type).fetch();
    }

    /**
     * 根据加载商户抵扣券
     * @param merchantId
     * @return
     */
    public static List<DiscountCoupon> findByMerchantAndType(long merchantId , CouponType type) {
        return DiscountCoupon.find("deleted = ? and  merchant.id = ? and type = ?  ", DeletedStatus.UN_DELETED ,  merchantId , type).fetch();
    }



    public static List<DiscountCoupon> findByAvailableByMerchantAndType(Merchant merchant , CouponType type) {
        return DiscountCoupon.find("deleted = ? and beginAt < ? and endAt > ? and merchant = ? and type = ? order by fullAmount desc", DeletedStatus.UN_DELETED , new Date() , new Date() , merchant , type).fetch();
    }

    /**
     * 检测代金券
     * @param order
     */
    public static void checkToCoupon(Order order) {
        checkToCoupon(order.webUser , order.merchant ,order.amount);
    }


    /**
     * 赠送特定代金券
     * @param webUser
     * @param discountCoupon
     */
    public static void giveByCoupon(WebUser webUser, DiscountCoupon discountCoupon) {
        if(webUser == null || discountCoupon == null) {
            Logger.info("discountCoupon 或者 WebUser 不存在。 不能充值卡券");
            return;
        }

        WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
        if(webUserCoupon == null) {
            webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
            new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
        } else {
//            if(discountCoupon.type.toString().indexOf("NO_BODY") < 1) {
//                webUserCoupon.amount += discountCoupon.amount;
//                webUserCoupon.modifyAt = new Date();
//                webUserCoupon.save();
//                new WebUserCouponHistory(webUserCoupon, discountCoupon.title, discountCoupon.amount).save();
//            }
        }
    }

    public static void giveSpecialCoupon(WebUser webUser, DiscountCoupon discountCoupon) {
        if(webUser == null || discountCoupon == null) {
            Logger.info("discountCoupon 或者 WebUser 不存在。 不能充值卡券");
            return;
        }

        WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
        if(webUserCoupon == null) {
            webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
            new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
        } else {
            if(discountCoupon.type == CouponType.NO_BODY) {
                if(webUserCoupon == null) {
                    webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
                    new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
                }
            }else if(discountCoupon.type == CouponType.FIRST_ORDER) {
                webUserCoupon.amount += discountCoupon.amount;
                webUserCoupon.modifyAt = new Date();
                webUserCoupon.save();
                new WebUserCouponHistory(webUserCoupon, discountCoupon.title, discountCoupon.amount).save();
            }else if(discountCoupon.type == CouponType.FULL_MONEY) {
                webUserCoupon.amount += discountCoupon.amount;
                webUserCoupon.modifyAt = new Date();
                webUserCoupon.save();
                new WebUserCouponHistory(webUserCoupon, "满金额就赠送代金券", discountCoupon.amount).save();
            }else if(discountCoupon.type == CouponType.SIGN_IN) {
//                WebUserCoupon webUserCoupon1 = WebUserCoupon.findByDiscountCoupon(discountCoupon);
//                if(webUserCoupon1 == null) {
                    webUserCoupon.amount += discountCoupon.amount;
                    webUserCoupon.modifyAt = new Date();
                    webUserCoupon.save();
                    new WebUserCouponHistory(webUserCoupon, "签到赠送代金券", discountCoupon.amount).save();
//                }
            }
        }
    }

    /**
     * 用户批量领取代金券
     * @param webUser
     * @param merchant
     * @param type
     * @param content
     */
    public static void giveCouponByType(WebUser webUser , Merchant merchant , CouponType type , String content) {
        List<DiscountCoupon> discountCouponList = DiscountCoupon.findByAvailableByMerchantAndType(merchant , type);
        WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
        for(DiscountCoupon discountCoupon : discountCouponList) {
            if(type.toString().indexOf("NO_BODY") > 0) {
                if(webUserCoupon == null) {
                    webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
                    new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
                }
            } else {
                if(webUserCoupon == null) {
                    webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
                    new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
                } else {
                    webUserCoupon.amount += discountCoupon.amount;
                    webUserCoupon.modifyAt = new Date();
                    webUserCoupon.save();
                    new WebUserCouponHistory(webUserCoupon, content, discountCoupon.amount).save();
                }
            }


        }
    }

    /**
     * 异步操作
     * 检查 赠送代金券功能
     * @param webUser
     * @param merchant
     */
    public static void checkToCoupon(final WebUser webUser , final Merchant merchant,final Double amount) {
        new Job() {
            @Override
            public void doJob() throws Exception {
                WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
                Long orderCount = Order.countByWebUser(webUser);
                List<DiscountCoupon> discountCouponList = DiscountCoupon.findByAvailableByMerchant(merchant);
                Boolean bol = true;
                for(DiscountCoupon discountCoupon : discountCouponList) {
                    // 如果用户没有 赠送
                    if(discountCoupon.type == CouponType.NO_BODY && webUserCoupon == null) {
                        webUserCoupon =  new WebUserCoupon(webUser , discountCoupon , discountCoupon.amount).save();
                        new WebUserCouponHistory(webUserCoupon , "用户没有代金券 自动初始化充值" , discountCoupon.amount).save();
                    }

                    //首次下单赠送
                    if(discountCoupon.type == CouponType.FIRST_ORDER && orderCount < 1) {
                        if(webUserCoupon == null) {
                            webUserCoupon = new WebUserCoupon(webUser, discountCoupon, discountCoupon.amount).save();
                            new WebUserCouponHistory(webUserCoupon, "用户没有代金券 自动初始化充值", discountCoupon.amount).save();
                        } else {
                            webUserCoupon.amount += discountCoupon.amount;
                            webUserCoupon.modifyAt = new Date();
                            webUserCoupon.save();
                            new WebUserCouponHistory(webUserCoupon, "首次下单赠送", discountCoupon.amount).save();
                        }
                    }
                    //满赠
                    if(discountCoupon.type == CouponType.FULL_MONEY && amount >= discountCoupon.fullAmount && bol) {
                        if(webUserCoupon == null) {
                            webUserCoupon = new WebUserCoupon(webUser, discountCoupon, discountCoupon.amount).save();
                            new WebUserCouponHistory(webUserCoupon, "用户没有代金券 自动初始化充值", discountCoupon.amount).save();
                        } else {
                            webUserCoupon.amount += discountCoupon.amount;
                            webUserCoupon.modifyAt = new Date();
                            webUserCoupon.save();
                            new WebUserCouponHistory(webUserCoupon, "单笔订单金额满就赠", discountCoupon.amount).save();
                        }
                        CacheHelper.setCache(GlobalConfig.WEIXIN_MP_SESSION_USER_FULL_MONEY_KEY + webUser.id, webUser.id);
                        bol = false;
                    }
                }
            }
        }.now();
    }

    //满一定金额就送代金券（固定金额）
    public static void giveUserCouponForMZ(Order order) {
        giveUserCouponForMZ(order.webUser,order.merchant,order.amount);
    }

    public static void giveUserCouponForMZ(final WebUser webUser , final Merchant merchant,final Double amount) {
//        new Job() {
//            @Override
//            public void doJob() throws Exception {
                List<DiscountCoupon> discountCouponList = DiscountCoupon.findByAvailableByMerchantAndType(merchant,CouponType.FULL_MONEY);
                Boolean bol = true;
                if(webUser != null && discountCouponList != null && discountCouponList.size() > 0){
                    for(DiscountCoupon discountCoupon : discountCouponList) {
                        if(amount >= discountCoupon.fullAmount && bol) {
                            DiscountCouponDetail webUserCoupon = DiscountCouponDetail.findByWebUserAndCoupon(webUser,discountCoupon);
                            if(discountCoupon.isAccumulation == null || !discountCoupon.isAccumulation) {
                                if(webUserCoupon != null && webUserCoupon.amount > 1) {
                                    continue;
                                }
                            }
                            DiscountCouponDetail discountCouponDetail =  DiscountCouponDetail.createOrUpdateDetail(webUser , discountCoupon , discountCoupon.amount);
                            new DiscountCouponDetailHistory(discountCouponDetail , discountCoupon.amount , discountCoupon.title +  "赠送" + discountCoupon.amount + "元").save();
                            CacheHelper.setCache(GlobalConfig.WEIXIN_MP_SESSION_USER_FULL_MONEY_KEY + webUser.id, webUser.id+"");
                            bol = false;
                        }
                    }
                }
//            }
//        }.now();
    }

    //赠送代金券，签到
    public static Map giveUserCouponForSignIn( WebUser webUser ,  DiscountCoupon discountCoupon) {
        Boolean bol = false;
        Map<String , Object> resultMap = new HashMap<>();
        if(webUser != null && discountCoupon != null ){
            DiscountCouponDetail webUserCoupon = DiscountCouponDetail.findByWebUserAndCoupon(webUser,discountCoupon);

            if(discountCoupon.isAccumulation == null || !discountCoupon.isAccumulation) {
                if(webUserCoupon != null && webUserCoupon.amount > 1) {
                    resultMap.put("success",false);
                    resultMap.put("msg","红包已存在 不能重复发送红包!");
                    return resultMap;
                }
            }

            // 计算出来的金额
            Double couponAmount = randomAmount(discountCoupon.minAmount , discountCoupon.maxAmount , discountCoupon.grade);
            BigDecimal b   =   new   BigDecimal(couponAmount);

            couponAmount = b.setScale(2,   BigDecimal.ROUND_HALF_UP).doubleValue();


            DiscountCouponDetail discountCouponDetail =  DiscountCouponDetail.createOrUpdateDetail(webUser , discountCoupon , couponAmount);
            new DiscountCouponDetailHistory(discountCouponDetail , couponAmount , discountCoupon.title +  "赠送" + couponAmount + "元").save();
            resultMap.put("success",true);
            resultMap.put("msg","恭喜您获得" + couponAmount + "元红包 请在 [我的]->[我的代金券]中查看");

//            for(DiscountCoupon discountCoupon : discountCouponList) {
//                if(amount >= discountCoupon.fullAmount && bol) {
//                    DiscountCouponDetail webUserCoupon = DiscountCouponDetail.findByWebUserAndCoupon(webUser,discountCoupon);
//                    if(discountCoupon.isAccumulation == null || !discountCoupon.isAccumulation) {
//                        if(webUserCoupon != null && webUserCoupon.amount > 1) {
//                            continue;
//                        }
//                    }
//                    DiscountCouponDetail discountCouponDetail =  DiscountCouponDetail.createOrUpdateDetail(webUser , discountCoupon , discountCoupon.amount);
//                    new DiscountCouponDetailHistory(discountCouponDetail , discountCoupon.amount , discountCoupon.title +  "赠送" + discountCoupon.amount + "元").save();
//                    CacheHelper.setCache(GlobalConfig.WEIXIN_MP_SESSION_USER_SIGN_IN_KEY + webUser.id, webUser.id);
//                    bol = false;
//                }
//            }
        }else {
            resultMap.put("success" , false);
            resultMap.put("msg" , "您要领取的红包不存在或已删除");
        }
        return resultMap;
    }

    public static Double randomAmount(Double minAmount , Double maxAmount , Integer grade) {
        List<Double> randomList = new ArrayList<>();
        for (int i = 0; i <= grade; i++) {
            if(i == 0) {
                randomList.add(minAmount);
            } else if(i == grade) {
                randomList.add(maxAmount);
            } else {
                randomList.add(maxAmount/grade*i);
            }
        }
        //打乱排序
        Collections.shuffle(randomList);
        if (randomList == null || randomList.size() == 0) {
            return minAmount;
        }
        // 获取1-最大值之间的一个随机数
        //如果随机数小于最小金额 或者大于最大金额，则重新获取

        double luckyNumber = 0 ;
        do{
            int luckyIndex = new Random().nextInt(randomList.size());
            luckyNumber = Double.valueOf(randomList.get(luckyIndex)) ;

        }while (luckyNumber < minAmount || luckyNumber > maxAmount  ) ;

        return luckyNumber;
    }

    public static Double disCountpayAmount(Double amount , WebUser webUser) {
        WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
        Logger.info("用户 : %s 代金券 : %s" , webUser.nickName , webUserCoupon);
        if(webUserCoupon != null && webUserCoupon.amount != null && webUserCoupon.amount > 0) {
            Double disCountPay = (amount * webUserCoupon.discountCoupon.avgProportion) / 100;
            if(webUserCoupon.amount > disCountPay) {
                return disCountPay;
            } else {
                return webUserCoupon.amount;
            }
        }
        return 0d;
    }

    public static Double disCountpayAmount(Double amount , WebUser webUser , Merchant merchant) {
        if(merchant.playCoupon != null && merchant.playCoupon) {
            WebUserCoupon webUserCoupon = WebUserCoupon.findByWebUser(webUser);
            Logger.info("用户 : %s 代金券 : %s", webUser.nickName, webUserCoupon);
            if (webUserCoupon != null && webUserCoupon.amount != null && webUserCoupon.amount > 0) {
                Double disCountPay = (amount * webUserCoupon.discountCoupon.avgProportion) / 100;
                if (webUserCoupon.amount > disCountPay) {
                    return disCountPay;
                } else {
                    return webUserCoupon.amount;
                }
            }
        }
        return 0d;

    }

}
